001 /* 002 * Copyright 2003-2005 The Apache Software Foundation 003 * Copyright 2005 Stephen McConnell 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package net.dpml.cli.builder; 018 019 import java.util.ArrayList; 020 import java.util.List; 021 022 import net.dpml.cli.Argument; 023 import net.dpml.cli.option.ArgumentImpl; 024 import net.dpml.cli.resource.ResourceConstants; 025 import net.dpml.cli.resource.ResourceHelper; 026 import net.dpml.cli.validation.Validator; 027 028 /** 029 * Builds Argument instances. 030 * 031 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 032 * @version 1.0.0 033 */ 034 public class ArgumentBuilder 035 { 036 /** i18n */ 037 private static final ResourceHelper RESOURCES = ResourceHelper.getResourceHelper(); 038 039 /** name of the argument. Used for display and lookups in CommandLine */ 040 private String m_name; 041 042 /** description of the argument. Used in the automated online help */ 043 private String m_description; 044 045 /** minimum number of values required */ 046 private int m_minimum; 047 048 /** maximum number of values permitted */ 049 private int m_maximum; 050 051 /** character used to separate the values from the option */ 052 private char m_initialSeparator; 053 054 /** character used to separate the values from each other */ 055 private char m_subsequentSeparator; 056 057 /** object that should be used to ensure the values are valid */ 058 private Validator m_validator; 059 060 /** used to identify the consume remaining option, typically "--" */ 061 private String m_consumeRemaining; 062 063 /** default values for argument */ 064 private List m_defaultValues; 065 066 /** id of the argument */ 067 private int m_id; 068 069 /** 070 * Creates a new ArgumentBuilder instance 071 */ 072 public ArgumentBuilder() 073 { 074 reset(); 075 } 076 077 /** 078 * Creates a new Argument instance using the options specified in this 079 * ArgumentBuilder. 080 * 081 * @return A new Argument instance using the options specified in this 082 * ArgumentBuilder. 083 */ 084 public final Argument create() 085 { 086 final Argument argument = 087 new ArgumentImpl( 088 m_name, 089 m_description, 090 m_minimum, 091 m_maximum, 092 m_initialSeparator, 093 m_subsequentSeparator, 094 m_validator, 095 m_consumeRemaining, 096 m_defaultValues, 097 m_id ); 098 reset(); 099 return argument; 100 } 101 102 /** 103 * Resets the ArgumentBuilder to the defaults for a new Argument. The 104 * method is called automatically at the end of a create() call. 105 * @return the argument builder 106 */ 107 public final ArgumentBuilder reset() 108 { 109 m_name = "arg"; 110 m_description = null; 111 m_minimum = 0; 112 m_maximum = Integer.MAX_VALUE; 113 m_initialSeparator = ArgumentImpl.DEFAULT_INITIAL_SEPARATOR; 114 m_subsequentSeparator = ArgumentImpl.DEFAULT_SUBSEQUENT_SEPARATOR; 115 m_validator = null; 116 m_consumeRemaining = "--"; 117 m_defaultValues = null; 118 m_id = 0; 119 return this; 120 } 121 122 /** 123 * Sets the name of the argument. The name is used when displaying usage 124 * information and to allow lookups in the CommandLine object. 125 * 126 * @see net.dpml.cli.CommandLine#getValue(String) 127 * 128 * @param newName the name of the argument 129 * @return this ArgumentBuilder 130 */ 131 public final ArgumentBuilder withName( final String newName ) 132 { 133 if( newName == null ) 134 { 135 throw new IllegalArgumentException( 136 RESOURCES.getMessage( 137 ResourceConstants.ARGUMENT_BUILDER_NULL_NAME ) ); 138 } 139 if( "".equals( newName ) ) 140 { 141 throw new IllegalArgumentException( 142 RESOURCES.getMessage( 143 ResourceConstants.ARGUMENT_BUILDER_EMPTY_NAME ) ); 144 } 145 m_name = newName; 146 return this; 147 } 148 149 /** 150 * Sets the description of the argument. 151 * 152 * The description is used when displaying online help. 153 * 154 * @param newDescription a description of the argument 155 * @return this ArgumentBuilder 156 */ 157 public final ArgumentBuilder withDescription( final String newDescription ) 158 { 159 m_description = newDescription; 160 return this; 161 } 162 163 /** 164 * Sets the minimum number of values needed for the argument to be valid. 165 * 166 * @param newMinimum the number of values needed 167 * @return this ArgumentBuilder 168 */ 169 public final ArgumentBuilder withMinimum( final int newMinimum ) 170 { 171 if( newMinimum < 0 ) 172 { 173 throw new IllegalArgumentException( 174 RESOURCES.getMessage( 175 ResourceConstants.ARGUMENT_BUILDER_NEGATIVE_MINIMUM ) ); 176 } 177 m_minimum = newMinimum; 178 return this; 179 } 180 181 /** 182 * Sets the maximum number of values allowed for the argument to be valid. 183 * 184 * @param newMaximum the number of values allowed 185 * @return this ArgumentBuilder 186 */ 187 public final ArgumentBuilder withMaximum( final int newMaximum ) 188 { 189 if( newMaximum < 0 ) 190 { 191 throw new IllegalArgumentException( 192 RESOURCES.getMessage( 193 ResourceConstants.ARGUMENT_BUILDER_NEGATIVE_MAXIMUM ) ); 194 } 195 m_maximum = newMaximum; 196 return this; 197 } 198 199 /** 200 * Sets the character used to separate the values from the option. When an 201 * argument is of the form -libs:dir1,dir2,dir3 the initialSeparator would 202 * be ':'. 203 * 204 * @param newInitialSeparator the character used to separate the values 205 * from the option 206 * @return this ArgumentBuilder 207 */ 208 public final ArgumentBuilder withInitialSeparator( 209 final char newInitialSeparator ) 210 { 211 m_initialSeparator = newInitialSeparator; 212 return this; 213 } 214 215 /** 216 * Sets the character used to separate the values from each other. When an 217 * argument is of the form -libs:dir1,dir2,dir3 the subsequentSeparator 218 * would be ','. 219 * 220 * @param newSubsequentSeparator the character used to separate the values 221 * from each other 222 * @return this ArgumentBuilder 223 */ 224 public final ArgumentBuilder withSubsequentSeparator( 225 final char newSubsequentSeparator ) 226 { 227 m_subsequentSeparator = newSubsequentSeparator; 228 return this; 229 } 230 231 /** 232 * Sets the validator instance used to perform validation on the Argument 233 * values. 234 * 235 * @param newValidator a Validator instance 236 * @return this ArgumentBuilder 237 */ 238 public final ArgumentBuilder withValidator( final Validator newValidator ) 239 { 240 if( newValidator == null ) 241 { 242 throw new IllegalArgumentException( 243 RESOURCES.getMessage( 244 ResourceConstants.ARGUMENT_BUILDER_NULL_VALIDATOR ) ); 245 } 246 m_validator = newValidator; 247 return this; 248 } 249 250 /** 251 * Sets the "consume remaining" option, defaults to "--". Use this if you 252 * want to allow values that might be confused with option strings. 253 * 254 * @param newConsumeRemaining the string to use for the consume 255 * remaining option 256 * @return this ArgumentBuilder 257 */ 258 public final ArgumentBuilder withConsumeRemaining( final String newConsumeRemaining ) 259 { 260 if( newConsumeRemaining == null ) 261 { 262 throw new IllegalArgumentException( 263 RESOURCES.getMessage( 264 ResourceConstants.ARGUMENT_BUILDER_NULL_CONSUME_REMAINING ) ); 265 } 266 if( "".equals( newConsumeRemaining ) ) 267 { 268 throw new IllegalArgumentException( 269 RESOURCES.getMessage( 270 ResourceConstants.ARGUMENT_BUILDER_EMPTY_CONSUME_REMAINING ) ); 271 } 272 m_consumeRemaining = newConsumeRemaining; 273 return this; 274 } 275 276 /** 277 * Sets the default value. 278 * 279 * @param defaultValue the default value for the Argument 280 * @return this ArgumentBuilder 281 */ 282 public final ArgumentBuilder withDefault( final Object defaultValue ) 283 { 284 if( defaultValue == null ) 285 { 286 throw new IllegalArgumentException( 287 RESOURCES.getMessage( 288 ResourceConstants.ARGUMENT_BUILDER_NULL_DEFAULT ) ); 289 } 290 291 if( m_defaultValues == null ) 292 { 293 m_defaultValues = new ArrayList( 1 ); 294 } 295 m_defaultValues.add( defaultValue ); 296 return this; 297 } 298 299 /** 300 * Sets the default values. 301 * 302 * @param newDefaultValues the default values for the Argument 303 * @return this ArgumentBuilder 304 */ 305 public final ArgumentBuilder withDefaults( final List newDefaultValues ) 306 { 307 if( newDefaultValues == null ) 308 { 309 throw new IllegalArgumentException( 310 RESOURCES.getMessage( 311 ResourceConstants.ARGUMENT_BUILDER_NULL_DEFAULTS ) ); 312 } 313 m_defaultValues = newDefaultValues; 314 return this; 315 } 316 317 /** 318 * Sets the id 319 * 320 * @param newId the id of the Argument 321 * @return this ArgumentBuilder 322 */ 323 public final ArgumentBuilder withId( final int newId ) 324 { 325 m_id = newId; 326 return this; 327 } 328 }